import os
import time
import re
import pickle


class FileCache:
    def __init__(self, config=None):
        options = {
            'file_path': 'cache',
            'expires': None
        }
        if type(config) is dict:
            options.update(config)
        self.options = options

    def get_file_full_path(self, file_name):
        op = self.options
        if op.get('file_path') == '':
            file_full_path = file_name
        else:
            file_full_path = op.get('file_path') + '/' + file_name
        file_full_path = re.sub(r'[\\/]+', '/', file_full_path)
        return file_full_path

    def write(self, cache_id, content, second=None):
        op = self.options
        file_full_path = self.get_file_full_path(cache_id)
        file_dir = os.path.dirname(file_full_path)
        if not os.path.isdir(file_dir):
            os.makedirs(file_dir)
        fh = open(file_full_path, 'wb')
        expire_time_value = self.get_expire_time_value(second)
        op['expires'] = expire_time_value
        cache_data = {'Content': content, 'Expires': expire_time_value}
        cache_bin_data = pickle.dumps(cache_data)
        fh.write(cache_bin_data)
        fh.close()

    def read(self, cache_id):
        file_full_path = self.get_file_full_path(cache_id)
        if os.path.isfile(file_full_path):
            fh = open(file_full_path, 'rb')
            cache_bin_data = fh.read()
            cache_data = pickle.loads(cache_bin_data)
            expires = cache_data.get('Expires')
            if self.is_expired(expires):
                content = None
            else:
                content = cache_data.get('Content')
            fh.close()
        else:
            content = None
        return content

    def delete(self, cache_id):
        result = False
        file_full_path = self.get_file_full_path(cache_id)
        if os.path.isfile(file_full_path):
            os.remove(file_full_path)
            result = True
        return result

    def get_expire_time_value(self, second):
        if type(second) is int:
            expire_time_stamp = time.time() + second
            expire_time_tuple = time.localtime(expire_time_stamp)
            expire_time_value = int(time.strftime('%Y%m%d%H%M%S', expire_time_tuple))
        else:
            op = self.options
            expire_time_value = op.get('expires')
            if type(expire_time_value) is str:
                expire_time_value = int(expire_time_value)
        return expire_time_value

    def is_expired(self, expires):
        if expires is None:
            result = False
        else:
            current_time_value = int(time.strftime('%Y%m%d%H%M%S'))
            if current_time_value >= expires:
                result = True
            else:
                result = False
        return result
